﻿<%@ Page Language="VB" AutoEventWireup="false" CodeFile="tableEditForm.aspx.vb" Inherits="forms_Custom_my_tableEditForm" %>

<!DOCTYPE>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="/InSiteWebApplication/Scripts/jquery-1.11.2.min.js" type="text/javascript"></script>
    <style type="text/css">
        
    body,table,tr,td,div,ul,li
    {
        margin:0px;
        padding:0px;
        --box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
        }
     .variableTable td,  .topRule td
     {         
        min-width:30px;
         }  
      .variableTable td,  .leftRule td
      {          
          min-height:20px;
          padding:5px;
          }
    .variableTable{
         margin: 0;
        border-collapse: collapse;
        border: 1px solid #ddd;
        max-width:100%;
        word-wrap: break-word;
        word-break: break-all; 
    }
    .variableTable td{
         border: 1px solid #ddd;
        text-align: center;
        font-size: 15px;    
    }
    .variableTable td>div
    {
        height:100%;        
        overflow:auto;
        cursor:text;
        }
    .cannotselect{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;-khtml-user-select:none;user-select:none;}
    
    td.selected{background:#0094ff;color:#fff}
    td.orgHide{display:none}
    td.hide{display:none}
    
    .topRule
    {
         border-collapse: collapse;
        }
     .topRule td
    {
        height:30px;        
        position:relative;
        border-right:1px solid #fff;                
        padding:0px 5px;
    }
     .topRule td div
    {
        position:absolute;
        font-size:16px;
        right:-3px;
        top:0px;
        width:10px;
        height:20px;
        cursor:default;
        color:#777;
        }
        
     .topRule td div,.leftRule td div
    {
            -moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;-khtml-user-select:none;user-select:none;
        }
        
    .leftRule
    {
        border-collapse: collapse;
        margin-right:10px;
        margin-top:30px;
        }
      .leftRule td
      {
          width:30px;
          position:relative;          
          border:1px solid #fff;
          }  
     .leftRule td div
     {
          position:absolute;
        font-size:16px;
        right:0px;
        bottom:-8px;
        cursor:default;
        color:#777;
         }
       ul.ruleContextmenu
       {
            list-style: none;            
             width:160px;
            height:120px;
            border:1px solid #eee;
            background-color:#fff;            
            display: none;
            position: absolute;
            
          box-shadow: 0px 5px 20px rgba(0,0,0,0.3);  
           }
        ul.ruleContextmenu>li
        {
             height:35px;
            line-height:35px;
            font-size:14px;
            color:#01AAED;
            text-align:center;
            border-bottom:1px solid #eee;
            cursor:pointer;
            }   
         ul.ruleContextmenu>li:hover
         {
             background-color:#eee;
             }
    </style>

</head>
<body>
    <form id="form1" runat="server">
    <div style="margin-bottom:10px">
        <asp:Button Text="按钮" runat="server"/>
    </div>
    <input id="ip" style="width:500px"/>
    
      <div id="dvEditTable">

      </div>

    </form>
</body>

<script type="text/javascript">
    document.body.onmousedown = function (e) {
        var e = e || window.event;
        var o = e.srcElement || e.target;
        var ruleContextmenu=$("body>.ruleContextmenu");
        if (ruleContextmenu.length > 0 && !ruleContextmenu[0].contains(o)) {
            $("body>.ruleContextmenu").remove();
        }
    }
   
    //表格行调整
    function tableDragRow(leftRuleID, tableID) {        
        var leftRule = document.getElementById(leftRuleID);
        var tableContent = document.getElementById(tableID);
        //右键菜单
        leftRule.onmousedown = function (e) {
            var e = e || window.event;
            var o = e.srcElement || e.target;
            $("body>.ruleContextmenu").remove();
            $(tableContent).find("td").removeClass("selected");
            if (e.button != "2" || o.tagName != "TD") return;

            for (i = 0; i < tableContent.rows[o.parentNode.rowIndex].cells.length; i++) {
                tableContent.rows[o.parentNode.rowIndex].cells[i].className += " selected";
            }
            var clientX = e.clientX;
            var clientY = e.clientY;
            //点击鼠标右键响应函数
            this.oncontextmenu = function (e) {
                $("body").append("<ul class='ruleContextmenu'><li>删除行</li><li>向上添加行</li><li>向下添加行</li></ul>");
                $("body>.ruleContextmenu").css({ "left": clientX, "top": clientY, "display": "block" });

                return false;
            }

        }

        for (i = 0; i < leftRule.rows.length; i++) {
            var slider;
            leftRule.rows[i].cells[0].children[0].onmousedown = function () {
                slider = this;
                slider.oldClientY = event.clientY;
                slider.currentStyle ? slider.currentStyle : window.getComputedStyle(slider, null);
                slider.style.bottom = slider.currentStyle.bottom;
                slider.style.color = '#000';
                slider.style.cursor = 'row-resize';
                slider.isSlider = true;
                document.body.onmousemove = function () {
                    if (slider.isSlider) {
                        var sliding = event.clientY - slider.oldClientY;
                        var td = slider.parentNode;
                        var tr = td.parentNode;
                        if (parseInt(td.currentStyle.height) + sliding < parseInt(td.currentStyle.minHeight)) return;
                        td.style.height = parseInt(td.currentStyle.height) + sliding;
                        td.height = td.style.height;
                        slider.oldClientY = event.clientY;

                        for (j = 0; j < tableContent.rows[tr.rowIndex].cells.length; j++) {
                            if (tableContent.rows[tr.rowIndex].cells[j].rowSpan != null && tableContent.rows[tr.rowIndex].cells[j].rowSpan >1)
                            { continue };
                            tableContent.rows[tr.rowIndex].cells[j].height = td.height;
                            tableContent.rows[tr.rowIndex].cells[j].style.height = td.height;
                        }

                        $("#ip").val(tableContent.rows[tr.rowIndex].cells.length); 
                    }
                }
                document.body.onmouseup = function () {
                    slider.style.color = '#777';
                    slider.style.cursor = 'default';
                    slider.isSlider = false;
                }
            }

            leftRule.rows[i].cells[0].children[0].onmouseup = function () {
                slider = this;
                slider.style.color = '#777';
                slider.style.cursor = 'default';
                slider.isSlider = false;
            }

        }
    }

    //删除列
    function delTablCol(topRuleObj, tableObj, ruleColObj) {
        var cellIndex = ruleColObj.cellIndex;
        //先删除内容表格对应列
        for (i = 0; i < tableObj.rows.length; i++) {
            cellIndex = ruleColObj.cellIndex;
           var td = tableObj.rows[i].cells[cellIndex];
           $(td).removeClass("selected");
           if (td.colSpan != null && td.colSpan > 1) {
               if ($(tableObj.rows[i].cells[cellIndex + 1]).css("display") == "none") {
                   td.parentNode.removeChild(tableObj.rows[i].cells[cellIndex + 1]);
                   td.colSpan -= 1;
               }
           }else {
               if ($(td).css("display") == "none") {
                   do {
                       cellIndex -= 1;
                       $("#ip").val(cellIndex);
                   }
                   while ($(tableObj.rows[i].cells[cellIndex]).css("display") == "none") 
                   if (tableObj.rows[i].cells[cellIndex].colSpan > 1) tableObj.rows[i].cells[cellIndex].colSpan -= 1;
               }
               td.parentNode.removeChild(td);
           }

       }
       //内容删除完后删除头部调整栏的列
       ruleColObj.parentNode.removeChild(ruleColObj);
       //移除右键菜单
       $("body>.ruleContextmenu").remove();
   }
   //添加列 type:0向前添加 1向后添加
   function addTablCol(topRuleObj, tableObj, ruleColObj, type) {
       var ruleColObjHtml = $(ruleColObj).prop("outerHTML");

       for (i = 0; i < tableObj.rows.length; i++) {
           var td = tableObj.rows[i].cells[ruleColObj.cellIndex];
           switch(type){
               case 0:
                   $(td).before("<td><div></div></td>");                 
                   break;
               case 1:
                   $(td).after("<td><div></div></td>");
                   break;

           }
       }
       //添加头部工具栏的列
       switch (type) {
           case 0:
               $(ruleColObj).before(ruleColObjHtml);
               break;
           case 1:
               $(ruleColObj).after(ruleColObjHtml);
               break;

       }     

       //移除右键菜单
       $("body>.ruleContextmenu").remove();
   }

   //删除行
   function delTablRow(leftRuleObj, tableObj, ruleColObj) {
    
   
   }
    
    function tableDragCol2(topRuleID,tableID) {
        var table = document.getElementById(topRuleID);
        var tableContent = document.getElementById(tableID);
        table.onmousedown = function (e) {
            var e = e || window.event;
            var o = e.srcElement || e.target;
            var contextMenu = $("body>.ruleContextmenu");
            contextMenu.remove();
            $(tableContent).find("td").removeClass("selected");
            if (e.button != "2" || o.tagName != "TD") return;

            for (i = 0; i < tableContent.rows.length; i++) {
                tableContent.rows[i].cells[o.cellIndex].className += " selected";
            }
            var clientX = e.clientX;
            var clientY = e.clientY;
            //点击鼠标右键响应函数
            this.oncontextmenu = function (e) {
                $("body").append("<ul class='ruleContextmenu'><li>删除列</li><li>向前添加列</li><li>向后添加列</li></ul>");
                contextMenu = $("body>.ruleContextmenu");
                contextMenu.css({ "left": clientX, "top": clientY, "display": "block" });
                contextMenu.find("li").eq(0).click(function () { delTablCol(table, tableContent, o) });
                contextMenu.find("li").eq(1).click(function () { addTablCol(table, tableContent, o, 0) });
                contextMenu.find("li").eq(2).click(function () { addTablCol(table, tableContent, o, 1) });
                return false;
            }

        }

        for (j = 0; j < table.rows[0].cells.length; j++) {
            var slider;
            table.rows[0].cells[j].children[0].onmousedown = function () {
                slider = this;
                slider.oldClientX = event.clientX;
                slider.currentStyle ? slider.currentStyle : window.getComputedStyle(slider, null);
                slider.style.right = slider.currentStyle.right;

                slider.style.color = '#000';
                slider.style.cursor = 'col-resize';

                slider.isSlider = true;
                document.body.onmousemove = function () {
                    if (slider.isSlider) {
                        var sliding = event.clientX - slider.oldClientX;

                        var td = slider.parentNode;

                        if (parseInt(td.currentStyle.width) + sliding < parseInt(td.currentStyle.minWidth)) return;

                        td.style.width = parseInt(td.currentStyle.width) + sliding;
                        td.width = td.style.width;
                        slider.oldClientX = event.clientX;

                        for (i = 0; i < tableContent.rows.length; i++) {
                            tableContent.rows[i].cells[td.cellIndex].width = td.width;
                            tableContent.rows[i].cells[td.cellIndex].style.width = td.width;
                        }

                        $("#ip").val(parseInt(td.currentStyle.width));

                    }

                }
                document.body.onmouseup = function () {
                    slider.style.color = '#777';
                    slider.style.cursor = 'default';
                    slider.isSlider = false;
                }
            }

            table.rows[0].cells[j].children[0].onmouseup = function () {
                slider = this;
                slider.style.color = '#777';
                slider.style.cursor = 'default';
                slider.isSlider = false;
            }
            
            
        }
    }

    function tableDragCol(id) {
        var tTD; //用来存储当前更改宽度的Table Cell,避免快速移动鼠标的问题
        var table = document.getElementById(id);        
        for (j = 0; j < table.rows[0].cells.length; j++) {
            table.rows[0].cells[j].onmousedown = function () {
                //记录单元格
                tTD = this;
                if (event.offsetX > tTD.offsetWidth - 10) {
                    tTD.mouseDown = true;
                    tTD.oldX = event.x;
                    tTD.oldWidth = tTD.offsetWidth;
                }
                //记录Table宽度
                //table = tTD; while (table.tagName != ‘TABLE') table = table.parentElement;
                //tTD.tableWidth = table.offsetWidth;
            };
            table.rows[0].cells[j].onmouseup = function () {
                //结束宽度调整
                if (tTD == undefined) tTD = this;
                tTD.mouseDown = false;
                tTD.style.cursor = 'default';
            };
            table.rows[0].cells[j].onmousemove = function () {
                //更改鼠标样式
                if (event.offsetX > this.offsetWidth - 10)
                    this.style.cursor = 'col-resize';
                else
                    this.style.cursor = 'default';
                //取出暂存的Table Cell
                if (tTD == undefined) tTD = this;
                //调整宽度
                if (tTD.mouseDown != null && tTD.mouseDown == true) {
                    tTD.style.cursor = 'default';

                    if (tTD.oldWidth + (event.x - tTD.oldX) > 0)
                        tTD.width = tTD.oldWidth + (event.x - tTD.oldX);
                    //调整列宽
                    tTD.style.width = tTD.width;
                    tTD.style.cursor = 'col-resize';

                    //调整该列中的每个Cell
                    table = tTD;
                    while (table.tagName != 'TABLE') table = table.parentElement;
                    for (j = 0; j < table.rows.length; j++) {
                        table.rows[j].cells[tTD.cellIndex].width = tTD.width;
                        table.rows[j].cells[tTD.cellIndex].style.width = tTD.width;
                    }
                    //调整整个表
                    //table.width = tTD.tableWidth + (tTD.offsetWidth – tTD.oldWidth);
                    //table.style.width = table.width;
                }
            };
        }
    }

    $.fn.tableMergeCells = function () {

        return this.each(function () {
            var tb = $(this), startTD, endTD, MMRC = { startRowIndex: -1, endRowIndex: -1, startCellIndex: -1, endCellIndex: -1 };
            //如果表格存在合并的，先补全td在初始化rc
            var tds = tb.find('td[colspan],td[rowspan]'), v, vc;
            if (tds.length) {
                tds.filter('[colspan]').each(function () {
                    v = (parseInt($(this).attr('colspan')) || 1) - 1;
                    if (v > 0) for (var i = 0; i < v; i++) $(this).after('<td class="orgHide"><div></div></td>');
                }).end().filter('[rowspan]').each(function () {
                    v = parseInt($(this).attr('rowspan')) || 1;
                    vc = parseInt($(this).attr('colspan')) || 1;
                    if (v > 1) {
                        for (var i = 1; i < v; i++) {
                            var td = $(this.parentNode.parentNode.rows[this.parentNode.rowIndex + i].cells[this.cellIndex]);
                            for (var j = 0; j < vc; j++) td.before('<td class="orgHide"><div></div></td>')
                        }
                    }
                });
            }
            //初始化所有单元格的行列下标内容并存储到dom对象中
            tb.find('tr').each(function (r, tr) {
                $('td', this).each(function (c, td) {
                    $(this).data('rc', {
                        r: r, c: c,
                        maxc: c + (parseInt(this.getAttribute('colspan')) || 1) - 1,
                        maxr: r + (parseInt(this.getAttribute('rowspan')) || 1) - 1
                    });
                })
            });

            //if (tds.length) tb.find('td.hide').remove(); //删除补全的td

            //添加表格禁止选择样式和事件
            tb.addClass('cannotselect').bind('selectstart', function () { return false });
            //选中单元格处理函数
            function addSelectedClass() {
                var selected = false, rc, t;
                tb.find('td').each(function () {
                    rc = $(this).data('rc');
                    //判断单元格左上坐标是否在鼠标按下和移动到的单元格行列区间内
                    selected = rc.r >= MMRC.startRowIndex && rc.r <= MMRC.endRowIndex && rc.c >= MMRC.startCellIndex && rc.c <= MMRC.endCellIndex;
                    if (!selected && rc.maxc) {//合并过的单元格，判断另外3（左下，右上，右下）个角的行列是否在区域内
                        selected =
                            (rc.maxr >= MMRC.startRowIndex && rc.maxr <= MMRC.endRowIndex && rc.c >= MMRC.startCellIndex && rc.c <= MMRC.endCellIndex) || //左下
                            (rc.r >= MMRC.startRowIndex && rc.r <= MMRC.endRowIndex && rc.maxc >= MMRC.startCellIndex && rc.maxc <= MMRC.endCellIndex) || //右上
                            (rc.maxr >= MMRC.startRowIndex && rc.maxr <= MMRC.endRowIndex && rc.maxc >= MMRC.startCellIndex && rc.maxc <= MMRC.endCellIndex); //右下

                    }
                    if (selected) { this.className += ' selected' };
                });
                var rangeChange = false;
                tb.find('td.selected').each(function () { //从已选中单元格中更新行列的开始结束下标
                    rc = $(this).data('rc');
                    t = MMRC.startRowIndex;
                    MMRC.startRowIndex = Math.min(MMRC.startRowIndex, rc.r);
                    rangeChange = rangeChange || MMRC.startRowIndex != t;

                    t = MMRC.endRowIndex;
                    MMRC.endRowIndex = Math.max(MMRC.endRowIndex, rc.maxr || rc.r);
                    rangeChange = rangeChange || MMRC.endRowIndex != t;

                    t = MMRC.startCellIndex;
                    MMRC.startCellIndex = Math.min(MMRC.startCellIndex, rc.c);
                    rangeChange = rangeChange || MMRC.startCellIndex != t;

                    t = MMRC.endCellIndex;
                    MMRC.endCellIndex = Math.max(MMRC.endCellIndex, rc.maxc || rc.c);
                    rangeChange = rangeChange || MMRC.endCellIndex != t;
                });
                //注意这里如果用代码选中过合并的单元格需要重新执行选中操作
                if (rangeChange) addSelectedClass();
            }
            function onMousemove(e) {//鼠标在表格单元格内移动事件
                e = e || window.event;
                var o = e.srcElement || e.target;
                if (o.tagName == 'TD' || o.parentNode.tagName == 'TD') {
                    endTD = (o.tagName == 'TD' ? o : o.parentNode);
                    var sRC = $(startTD).data('rc'), eRC = $(endTD).data('rc'), rc;
                    MMRC.startRowIndex = Math.min(sRC.r, eRC.r);
                    MMRC.startCellIndex = Math.min(sRC.c, eRC.c);
                    MMRC.endRowIndex = Math.max(sRC.r, eRC.r);
                    MMRC.endCellIndex = Math.max(sRC.c, eRC.c);
                    tb.find('td').removeClass('selected');
                    addSelectedClass();
                }
            }
            function onMouseup(e) {//鼠标弹起事件
                tb.unbind({ mouseup: onMouseup, mousemove: onMousemove });
                if (startTD && endTD && startTD != endTD && confirm('确认合并？！')) {//开始结束td不相同确认合并
                    var tds = tb.find('td.selected'), firstTD = tds.eq(0), index = -1, t, addBR
                        , html = tds.filter(':gt(0)').map(function () {
                            t = this.parentNode.rowIndex;
                            addBR = index != -1 && index != t;
                            index = t;
                            return (addBR ? '<br>' : '') + this.children[0].innerHTML
                        }).get().join(''); //合并后的分隔符

                    //tds.filter(':gt(0)').remove(); 
                    tds.filter(':gt(0)').addClass("hide");

                    firstTD.children('div:first').append('' + html.replace(/，(<br>)/g, '$1')).end().css("height","100%");

                    //更新合并的第一个单元格的缓存rc数据为所跨列和行
                    var rc = firstTD.attr({ colspan: MMRC.endCellIndex - MMRC.startCellIndex + 1, rowspan: MMRC.endRowIndex - MMRC.startRowIndex + 1 }).data('rc');

                    rc.maxc = rc.c + MMRC.endCellIndex - MMRC.startCellIndex; rc.maxr = rc.r + MMRC.endRowIndex - MMRC.startRowIndex;

                    firstTD.data('rc', rc);

                }
                tb.find('td').removeClass('selected');
                startTD = endTD = null;
            }
            function onMousedown(e) {
                var o = e.srcElement || e.target;
                if (o.tagName == 'TD' || o.parentNode.tagName == 'TD') {
                    startTD = (o.tagName == 'TD' ? o : o.parentNode);
                    tb.bind({ mouseup: onMouseup, mousemove: onMousemove });
                }
            }
            tb.mousedown(onMousedown);
        });
    };

    //tableDragCol2('tbRule');
  //$('.table').tableMergeCells();
</script>

 <script type="text/javascript">
     function editTableCell(tableID) {
         var tableContent = document.getElementById(tableID);       

         for (i = 0; i < tableContent.rows.length; i++) {
             for (j = 0; j < tableContent.rows[i].cells.length; j++) {
                 tableContent.rows[i].cells[j].ondblclick = function () {
                     this.children[0].contentEditable = "true";
                 }
             }
         }
     }


     $.fn.TableRender = function (cols, rows, colSize, rowSize) {
         var reg = /^[1-9]+[0-9]*]*$/;
         if (cols == null || rows == null) return alert(cols + "和" + rows + ",必填");

         if (reg.test(cols) == false || reg.test(rows) == false) return alert("所传参数必须都为数字");

         if (colSize == null) { colSize = 30 } else {
             if (reg.test(colSize) == false) {
                 return alert("所传参数必须都为数字");
             } else if (colSize < 30) {
                 colSize = 30;
             }
         };
         if (rowSize == null) { rowSize = 20 } else {
             if (reg.test(rowSize) == false) {
                 return alert("所传参数必须都为数字");
             } else if (rowSize < 20) {
                 rowSize = 20;
             }
         };

         var curObj = $(this);
         var topRuleId = curObj.attr("id") + "-topRule", leftRuleId = curObj.attr("id") + "-leftRule", mainBodyId = curObj.attr("id") + "-mainBoody";
         var leftID = curObj.attr("id") + "-left", rightID = curObj.attr("id") + "-right"

         curObj.css({ "position": "relative" });
         curObj.append("<div id='" + leftID + "' style='float:left;position:relative'></div><div id='" + rightID + "' style='float:left;position:relative'></div>");
         
         var $topRule = $("<table></table>");
         $topRule.attr("id", topRuleId);
         $topRule.addClass("topRule");

         var $topRuleTr = $("<tr></tr>");
         for (i = 0; i < cols; i++) {
             $topRuleTr.append("<td><div>&#9660</div></td>");
         }
         $topRule.append($topRuleTr);
         $("#" + rightID).append($topRule);

         //左边调整区域
         var $leftRule = $("<table></table>"), $leftRuleBody = $("<tbody></tbody>");
         $leftRule.attr("id", leftRuleId);
         $leftRule.addClass("leftRule");
         for (i = 0; i < rows; i++) {
             $leftRuleBody.append("<tr><td><div>&#9658</div></td></tr>");
         }
         $leftRule.append($leftRuleBody);
         $("#" + leftID).append($leftRule);

         //主内容表格区域
         var $minTable = $("<table></table>"), $mainBody = $("<tbody></tbody>"), $mainTr = $("<tr></tr>");
         $minTable.addClass("variableTable");
         $minTable.attr("id", mainBodyId);
         for (i = 0; i < cols; i++) {
             $mainTr.append("<td><div >" + i + "</div></td>");
         }
         for (i = 0; i < rows; i++) {
             $mainBody.append($mainTr.prop('outerHTML'));
         }
         $minTable.append($mainBody);
         $("#" + rightID).append($minTable);

         //调整高宽
         curObj.find(".variableTable td").css({ "width": colSize, "height": rowSize });
         curObj.find(".variableTable td").attr({ "width": colSize, "height": rowSize });

         curObj.find(".topRule td").css({ "width": colSize });
         curObj.find(".topRule td").attr("width", colSize);

         curObj.find(".leftRule td").css({ "Height": rowSize }); //curObj.find(".variableTable td").outerHeight()
         curObj.find(".leftRule td").attr("Height", rowSize);

         //赋予特性
         tableDragCol2(topRuleId, mainBodyId);
         tableDragRow(leftRuleId, mainBodyId);
         $('#' + mainBodyId).tableMergeCells();
         editTableCell(mainBodyId);

     }

     $("#dvEditTable").TableRender(20, 10, 50, 30);
    </script>

</html>
